#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
统一配置对象 - 强类型配置
"""

import re
import copy
import logging
from dataclasses import dataclass, field
from typing import Dict, List, Optional, Tuple
from .builtin_config_define import BuiltinConfigDefine

# 获取日志记录器
logger = logging.getLogger(__name__)

@dataclass
class ReservedSymbols:
    """保留符号配置"""
    language_keywords: Dict[str, List[str]] = field(default_factory=dict)
    system_types: List[str] = field(default_factory=list)
    system_methods: List[str] = field(default_factory=list)
    system_prefixes: Dict[str, List[str]] = field(default_factory=dict)
    lifecycle_patterns: Dict[str, List[str]] = field(default_factory=dict)
    common_annotations: Dict[str, List[str]] = field(default_factory=dict)
    user_reserved: Dict[str, List[str]] = field(default_factory=dict)
    user_patterns: List[str] = field(default_factory=list)

    def __post_init__(self):
        """初始化后加载内置配置并构建索引"""
        if not self.language_keywords:  # 只有当为空时才加载
            builtin = BuiltinConfigDefine()
            self.language_keywords = copy.deepcopy(builtin.LANGUAGE_KEYWORDS)
            self.system_types = list(builtin.SYSTEM_TYPES)
            self.system_methods = list(builtin.SYSTEM_METHODS)
            self.system_prefixes = copy.deepcopy(builtin.SYSTEM_PREFIXES)
            self.lifecycle_patterns = copy.deepcopy(builtin.LIFECYCLE_PATTERNS)
            self.common_annotations = copy.deepcopy(builtin.COMMON_ANNOTATIONS)

        # 构建性能优化索引
        self._build_indexes()

    def _build_indexes(self):
        """构建性能优化索引（O(n)一次性构建）"""
        # 1. 构建哈希集合索引 - 用于 O(1) 查找
        self._all_keywords_set = set()
        self._keywords_by_lang = {}
        for lang, keywords in self.language_keywords.items():
            keyword_set = set(keywords)
            self._keywords_by_lang[lang] = keyword_set
            self._all_keywords_set.update(keyword_set)

        self._system_types_set = set(self.system_types)
        self._system_methods_set = set(self.system_methods)

        # 构建用户保留符号集合
        self._user_reserved_set = set()
        self._user_reserved_by_lang = {}
        for lang, reserved in self.user_reserved.items():
            reserved_set = set(reserved)
            self._user_reserved_by_lang[lang] = reserved_set
            self._user_reserved_set.update(reserved_set)

        # 构建注解集合
        self._annotations_set = set()
        self._annotations_by_lang = {}
        for lang, annotations in self.common_annotations.items():
            annotation_set = set(annotations)
            self._annotations_by_lang[lang] = annotation_set
            self._annotations_set.update(annotation_set)

        # 2. 构建前缀树（Trie）- 用于快速前缀匹配
        self._prefix_tries = {}
        for platform, prefixes in self.system_prefixes.items():
            self._prefix_tries[platform] = self._build_prefix_trie(prefixes)

        # 3. 预编译正则表达式模式
        self._lifecycle_regexes = {}
        for platform, patterns in self.lifecycle_patterns.items():
            self._lifecycle_regexes[platform] = [re.compile(p) for p in patterns]

        self._user_pattern_regexes = [re.compile(p) for p in self.user_patterns]

    def _build_prefix_trie(self, prefixes: List[str]) -> Dict:
        """构建前缀树用于快速前缀匹配

        示例: ['NS', 'UI', 'CF'] ->
        {
            'N': {'S': {'$': True}},
            'U': {'I': {'$': True}},
            'C': {'F': {'$': True}}
        }
        """
        trie = {}
        for prefix in prefixes:
            node = trie
            for char in prefix:
                node = node.setdefault(char, {})
            node['$'] = True  # 标记前缀结束
        return trie

    def _has_system_prefix(self, symbol: str, trie: Dict) -> bool:
        """使用前缀树快速检查符号是否有系统前缀

        同时检查前缀后是否紧跟大写字母（如 NSString 而非 NSstring）
        """
        if not trie:
            return False

        node = trie

        for i, char in enumerate(symbol):
            if '$' in node:
                # 找到前缀结束标记
                # 检查是否符合规则：前缀后应该紧跟大写字母
                if i < len(symbol) and symbol[i].isupper():
                    return True

            if char not in node:
                return False

            node = node[char]

        # 检查最后一个位置
        return '$' in node

    def is_reserved(self, symbol: str, language: str = "", context: str = "") -> Tuple[bool, str]:
        """
        统一的保留符号检查

        性能提升：
        - 使用哈希集合: O(n) -> O(1)
        - 使用前缀树: O(n*m) -> O(m) where m = 符号长度
        - 预编译正则: 避免重复编译开销

        返回 (是否保留, 原因)
        """
        # O(1) - 检查特定语言的关键字（如果指定了语言）
        if language and language in self._keywords_by_lang:
            if symbol in self._keywords_by_lang[language]:
                return True, f"{language}语言关键字"

        # O(1) - 检查所有语言的关键字（兼容混编）
        if symbol in self._all_keywords_set:
            # 找出是哪个语言的关键字（用于详细报告）
            for lang, keyword_set in self._keywords_by_lang.items():
                if symbol in keyword_set:
                    return True, f"{lang}语言关键字"

        # O(1) - 检查系统类型
        if symbol in self._system_types_set:
            return True, "系统类型"

        # O(1) - 检查系统方法
        if symbol in self._system_methods_set:
            return True, "系统方法"

        # O(m) - 使用前缀树检查系统前缀 (m = 符号长度)
        platform = self._get_platform_from_context(context)
        if platform and platform in self._prefix_tries:
            if self._has_system_prefix(symbol, self._prefix_tries[platform]):
                return True, f"{platform}系统前缀"

        # 如果没有指定平台或为混合模式，检查所有平台的前缀
        if not platform or platform == 'mixed':
            for plat, trie in self._prefix_tries.items():
                if self._has_system_prefix(symbol, trie):
                    return True, f"{plat}系统前缀"

        # O(p) - 检查生命周期模式 (p = 预编译模式数量，通常 < 10)
        if platform and platform in self._lifecycle_regexes:
            for regex in self._lifecycle_regexes[platform]:
                if regex.match(symbol):
                    return True, f"{platform}生命周期方法"

        # O(1) - 检查注解（特定语言）
        if language and language in self._annotations_by_lang:
            if symbol in self._annotations_by_lang[language]:
                return True, f"{language}注解"

        # O(1) - 检查注解（所有）
        if symbol in self._annotations_set:
            for lang, annotation_set in self._annotations_by_lang.items():
                if symbol in annotation_set:
                    return True, f"{lang}注解"

        # O(1) - 检查用户自定义保留词（特定语言）
        if language and language in self._user_reserved_by_lang:
            if symbol in self._user_reserved_by_lang[language]:
                return True, "用户自定义保留词"

        # O(1) - 检查用户自定义保留词（所有）
        if symbol in self._user_reserved_set:
            return True, "用户自定义保留词"

        # O(q) - 检查用户自定义模式 (q = 用户模式数量，通常 < 5)
        for regex in self._user_pattern_regexes:
            if regex.match(symbol):
                return True, "用户自定义模式"

        return False, ""

    def rebuild_indexes(self):
        """外部更新数据后重建索引用于保持检测正确性"""
        self._build_indexes()
    
    def _get_platform_from_context(self, context: str) -> Optional[str]:
        """从上下文推断平台"""
        if context in ('ios', 'swift', 'objc'):
            return 'ios'
        elif context in ('android', 'kotlin', 'java'):
            return 'android'
        elif context == 'mixed':
            return None  # 混合平台需要检查所有
        return None

@dataclass
class ObfuscationRules:
    """混淆规则配置"""
    enabled_languages: List[str] = field(default_factory=lambda: ['swift', 'objc', 'kotlin', 'java'])
    
    # 符号类型控制
    symbol_types: Dict[str, bool] = field(default_factory=lambda: {
        'classes': True,
        'structs': True,
        'enums': True,
        'protocols': True,
        'interfaces': True,
        'methods': True,
        'functions': True,
        'properties': True,
        'fields': True,
        'constants': True,
        'variables': False,  # 默认不混淆局部变量
        'typedefs': True,
        'macros': False  # 默认不混淆宏
    })
    
    # 命名策略
    naming_strategy: str = "hybrid"  # random, dictionary, hybrid
    use_words_file: bool = True
    use_synonym_generator: bool = True
    
    # 长度控制
    min_length: int = 3
    max_length: int = 20
    
    # 随机化参数
    random_prefix: str = "Z"
    random_suffix: str = ""
    fallback_chars: str = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
    
    # 冲突避免
    avoid_conflicts: bool = True
    avoid_system_prefixes: bool = True

@dataclass
class FileFilters:
    """文件过滤配置"""
    include_extensions: List[str] = field(default_factory=lambda: ['.h', '.java', '.kt', '.m', '.mm', '.swift'])
    exclude_directories: List[str] = field(default_factory=lambda: [
        'Pods', 'thirdLibs', '.git', 'build', 'DerivedData', 
        'node_modules', '.gradle', 'gradle', 'target', 'out'
    ])
    exclude_files: List[str] = field(default_factory=lambda: [
        '.DS_Store', 'Podfile.lock', 'Package.resolved', 
        'gradle.properties', 'local.properties'
    ])
    
    def should_process_file(self, file_path: str) -> bool:
        """检查文件是否应该被处理"""
        import os
        
        # 检查扩展名
        _, ext = os.path.splitext(file_path)
        if ext not in self.include_extensions:
            return False
        
        # 检查排除的目录
        path_parts = file_path.split(os.sep)
        for exclude_dir in self.exclude_directories:
            if exclude_dir in path_parts:
                return False
        
        # 检查排除的文件
        filename = os.path.basename(file_path)
        if filename in self.exclude_files:
            return False
        
        return True

@dataclass
class AdvancedFeatures:
    """高级功能配置"""
    # 死代码注入 - 在现有函数中插入永不执行的分支
    dead_code_enabled: bool = False
    dead_code_complexity: str = "medium"  # low, medium, high, extreme
    dead_code_branches_per_function: int = 2
    dead_code_injection_probability: float = 0.3  # 注入概率

    # 代码注入 - 在现有代码中注入混淆逻辑
    injection_enabled: bool = False
    injection_content_file: str = "resources/inject.txt"
    injection_target_dirs: List[str] = field(default_factory=list)
    injection_white_list_folders: List[str] = field(default_factory=list)

    # AST功能控制
    use_ast_injection: bool = True  # 默认使用AST注入
    use_ast_extraction: bool = True  # 默认使用AST提取
    
    # 垃圾代码生成 - 生成独立的垃圾类文件
    dummy_code_enabled: bool = False
    dummy_code_count: int = 10
    dummy_code_complexity: str = "medium"  # low, medium, high
    dummy_code_white_list_folders: List[str] = field(default_factory=list)
    dummy_code_add_properties: bool = True
    dummy_code_linker_enabled: bool = True
    dummy_code_linker_file: str = "DummyCodeLinker.m"
    
    # 深度混淆
    deep_obfuscation_enabled: bool = False

    # 资源混淆
    resource_obfuscation_enabled: bool = False
    image_obfuscation_enabled: bool = False
    rename_resources: bool = False
    modify_md5: bool = False

    # 并行执行
    parallel_enabled: bool = False
    parallel_workers: int = 0
    
    # Xcode集成
    xcode_auto_add: bool = False
    xcode_project_file: str = ""
    xcode_target: str = ""

    # LSP 集成 (Language Server Protocol)
    lsp_enabled: bool = False  # 启用 LSP 进行精确符号重命名
    lsp_fallback_to_ast: bool = True  # LSP 失败时回退到 AST
    lsp_timeout: int = 30  # LSP 操作超时时间（秒）

@dataclass
class LoggingConfig:
    """日志配置"""
    verbose: bool = False
    log_file: str = "logs/obfuscation.log"
    log_level: str = "INFO"  # DEBUG, INFO, WARNING, ERROR
    log_each_symbol: bool = False
    colored_output: bool = True

@dataclass
class ValidationConfig:
    """代码验证配置"""
    enabled: bool = True
    levels: List[str] = field(default_factory=lambda: ['syntax', 'ast'])  # syntax, ast, ide
    fail_on_syntax_error: bool = False  # 语法错误时是否回滚
    fail_on_ast_error: bool = False  # AST错误时是否回滚
    ide_validation_on_complete: bool = True  # 完成后是否进行IDE验证
    save_validation_reports: bool = True  # 是否保存验证报告
    max_errors_to_show: int = 10  # 最多显示的错误数量

@dataclass
class AnalysisConfig:
    """分析配置"""
    # AST提取选项
    require_ast: bool = False           # 要求AST提取（无编译器时报错）
    allow_fallback: bool = True         # 允许降级到正则提取
    log_fallback: bool = True           # 记录降级事件
    ast_timeout: int = 30               # AST提取超时（秒）

    # 编译器路径（可选，优先级最高）
    swiftc_path: Optional[str] = None
    clang_path: Optional[str] = None
    kotlinc_path: Optional[str] = None
    javac_path: Optional[str] = None

    # 依赖分析增强配置
    extra_global_headers: Dict[str, List[str]] = field(default_factory=dict)
    extra_header_search_paths: List[str] = field(default_factory=list)

@dataclass
class ProcessingConfig:
    """
    统一的处理和批处理配置

    整合了 BatchConfig 和 ProcessorConfig 的功能，提供统一的配置接口。
    """
    # 并行处理配置
    max_workers: int = 4                    # 最大工作线程数
    parallel_batches: int = 4               # 并行批处理数

    # 批处理配置
    min_batch_size: int = 10                # 最小批大小
    max_batch_size: int = 100               # 最大批大小
    max_wait_time: float = 1.0              # 最大等待时间（秒）
    batch_timeout: float = 0.5              # 批处理超时（秒）
    max_batch_memory: int = 100 * 1024 * 1024  # 最大批内存（100MB）

    # 处理策略
    strategy: str = "adaptive"              # 处理策略：adaptive, size_based, time_based, count_based

    # 优化选项
    enable_compression: bool = False        # 是否启用压缩
    enable_caching: bool = True             # 是否启用缓存
    enable_load_balancing: bool = True      # 是否启用负载均衡

    # 重试配置
    retry_count: int = 3                    # 重试次数
    retry_delay: float = 1.0                # 重试延迟（秒）

@dataclass
class BuiltinSettings:
    """内建设置（用于AST等核心功能）"""
    extraction_mode: str = "ast"  # ast, regex, auto
    reserved_symbols: ReservedSymbols = field(default_factory=ReservedSymbols)

@dataclass
class BuiltInConfig:
    """统一配置对象"""
    # 基础配置
    project_path: str = ""
    output_dir: str = "output"
    backup_dir: str = "backups"
    temp_dir: str = "temp"
    log_dir: str = "logs"
    dry_run: bool = False
    mode: str = "mixed"  # swift, objc, kotlin, java, mixed, android, ios
    platform: str = "auto"  # auto, ios, android

    # 核心配置组件
    builtin: BuiltinSettings = field(default_factory=BuiltinSettings)
    reserved_symbols: ReservedSymbols = field(default_factory=ReservedSymbols)
    obfuscation_rules: ObfuscationRules = field(default_factory=ObfuscationRules)
    file_filters: FileFilters = field(default_factory=FileFilters)
    advanced_features: AdvancedFeatures = field(default_factory=AdvancedFeatures)
    logging: LoggingConfig = field(default_factory=LoggingConfig)
    validation: ValidationConfig = field(default_factory=ValidationConfig)
    analysis: AnalysisConfig = field(default_factory=AnalysisConfig)
    processing: ProcessingConfig = field(default_factory=ProcessingConfig)
    
    # 文件列表 - 用于快速测试
    swift_files: List[str] = field(default_factory=list)
    objc_files: List[str] = field(default_factory=list)
    java_files: List[str] = field(default_factory=list)
    kotlin_files: List[str] = field(default_factory=list)
    
    # 符号过滤器
    symbol_min_length: int = 3
    symbol_max_length: int = 50
    exclude_symbol_prefixes: List[str] = field(default_factory=lambda: ['_', 'test', 'Test'])
    exclude_symbol_suffixes: List[str] = field(default_factory=lambda: ['Test', 'Spec', 'Mock'])
    
    
    def is_symbol_safe_to_obfuscate(self, symbol: str, language: str = "", context: str = "") -> Tuple[bool, str]:
        """
        检查符号是否可以安全混淆
        返回 (是否安全, 原因)
        """
        # 检查保留符号
        is_reserved, reason = self.reserved_symbols.is_reserved(symbol, language, context)
        if is_reserved:
            return False, f"保留符号: {reason}"
        
        # 检查长度
        if len(symbol) < self.symbol_min_length:
            return False, f"符号太短 (< {self.symbol_min_length})"
        
        if len(symbol) > self.symbol_max_length:
            return False, f"符号太长 (> {self.symbol_max_length})"
        
        # 检查前缀
        for prefix in self.exclude_symbol_prefixes:
            if symbol.startswith(prefix):
                return False, f"排除前缀: {prefix}"
        
        # 检查后缀
        for suffix in self.exclude_symbol_suffixes:
            if symbol.endswith(suffix):
                return False, f"排除后缀: {suffix}"
        
        return True, ""
    
    def get_platform_context(self) -> str:
        """获取平台上下文"""
        if self.platform == 'ios':
            return 'ios'
        elif self.platform == 'android':
            return 'android'
        else:
            return self.mode if self.mode in ('ios', 'android') else 'mixed'
    
    def is_language_enabled(self, language: str) -> bool:
        """检查语言是否启用混淆"""
        return language in self.obfuscation_rules.enabled_languages
    
    def is_symbol_type_enabled(self, symbol_type: str) -> bool:
        """检查符号类型是否启用混淆"""
        return self.obfuscation_rules.symbol_types.get(symbol_type, False)

    def info(self, message: str):
        """信息日志方法 - 兼容性方法"""
        if self.logging.verbose:
            logger.info(message)

    def warning(self, message: str):
        """警告日志方法 - 兼容性方法"""
        logger.warning(message)

    def error(self, message: str):
        """错误日志方法 - 兼容性方法"""
        logger.error(message)

    def debug(self, message: str):
        """调试日志方法 - 兼容性方法"""
        if self.logging.log_level == "DEBUG":
            logger.debug(message)

    def validate(self) -> List[str]:
        """
        验证配置的有效性，返回错误列表

        增加了高级功能配置的依赖关系验证
        """
        errors = []
        warnings = []

        # === 基础验证 ===

        # 检查必需字段
        if not self.project_path:
            errors.append("project_path 不能为空")

        # 检查路径有效性
        import os
        if self.project_path and not os.path.exists(self.project_path):
            errors.append(f"项目路径不存在: {self.project_path}")

        # 检查语言配置
        valid_languages = {'swift', 'objc', 'kotlin', 'java'}
        for lang in self.obfuscation_rules.enabled_languages:
            if lang not in valid_languages:
                errors.append(f"不支持的语言: {lang}")

        # 检查命名策略
        valid_strategies = {'random', 'dictionary', 'hybrid'}
        if self.obfuscation_rules.naming_strategy not in valid_strategies:
            errors.append(f"不支持的命名策略: {self.obfuscation_rules.naming_strategy}")

        # 检查长度配置
        if self.symbol_min_length > self.symbol_max_length:
            errors.append("符号最小长度不能大于最大长度")

        if self.symbol_min_length < 1:
            errors.append("符号最小长度必须大于0")

        if self.symbol_max_length > 200:
            warnings.append("符号最大长度过大(>200)，可能导致问题")

        # === 高级功能交叉验证 ===

        # 代码注入验证
        if self.advanced_features.injection_enabled:
            if not self.advanced_features.injection_content_file:
                errors.append("代码注入已启用，但未指定内容文件(injection_content_file)")
            elif not os.path.exists(self.advanced_features.injection_content_file):
                errors.append(f"代码注入内容文件不存在: {self.advanced_features.injection_content_file}")

            if not self.advanced_features.injection_target_dirs:
                warnings.append("代码注入已启用，但未指定目标目录，将应用到所有目录")

        # 垃圾代码生成验证
        if self.advanced_features.dummy_code_enabled:
            if self.advanced_features.dummy_code_count < 1:
                errors.append("垃圾代码数量必须大于0")

            if self.advanced_features.dummy_code_count > 1000:
                warnings.append("垃圾代码数量过大(>1000)，可能严重影响编译时间")

            valid_complexity = {'low', 'medium', 'high'}
            if self.advanced_features.dummy_code_complexity not in valid_complexity:
                errors.append(f"垃圾代码复杂度无效: {self.advanced_features.dummy_code_complexity}")

            # 检查Linker文件配置
            if self.advanced_features.dummy_code_linker_enabled:
                if not self.advanced_features.dummy_code_linker_file:
                    errors.append("垃圾代码Linker已启用，但未指定Linker文件名")

        # 死代码注入验证
        if self.advanced_features.dead_code_enabled:
            valid_complexity = {'low', 'medium', 'high'}
            if self.advanced_features.dead_code_complexity not in valid_complexity:
                errors.append(f"死代码复杂度无效: {self.advanced_features.dead_code_complexity}")

            if self.advanced_features.dead_code_branches_per_function < 1:
                errors.append("死代码分支数必须大于0")

            if self.advanced_features.dead_code_branches_per_function > 10:
                warnings.append("死代码分支数过大(>10)，可能导致代码臃肿")

            if not (0 <= self.advanced_features.dead_code_injection_probability <= 1):
                errors.append("死代码注入概率必须在0-1之间")

        # 资源混淆验证
        if self.advanced_features.resource_obfuscation_enabled:
            if not any([
                self.advanced_features.image_obfuscation_enabled,
                self.advanced_features.rename_resources,
                self.advanced_features.modify_md5
            ]):
                warnings.append("资源混淆已启用，但未启用任何具体功能")

        # Xcode集成验证
        if self.advanced_features.xcode_auto_add:
            if not self.advanced_features.xcode_project_file:
                errors.append("Xcode自动添加已启用，但未指定项目文件")
            elif not os.path.exists(self.advanced_features.xcode_project_file):
                errors.append(f"Xcode项目文件不存在: {self.advanced_features.xcode_project_file}")

            if not self.advanced_features.xcode_target:
                warnings.append("Xcode自动添加已启用，但未指定目标，将使用第一个目标")

        # 验证配置验证
        if self.validation.enabled:
            valid_levels = {'syntax', 'ast', 'ide'}
            for level in self.validation.levels:
                if level not in valid_levels:
                    errors.append(f"验证级别无效: {level}")

            if not self.validation.levels:
                warnings.append("验证已启用，但未指定任何验证级别")

        # 并行执行验证
        if self.advanced_features.parallel_enabled:
            if self.advanced_features.parallel_workers < 0:
                errors.append("并行工作进程数不能为负数")

            if self.advanced_features.parallel_workers > 32:
                warnings.append("并行工作进程数过大(>32)，可能导致系统资源耗尽")

        # 平台和模式一致性验证
        if self.platform != 'auto':
            if self.platform == 'ios':
                if not any(lang in self.obfuscation_rules.enabled_languages for lang in ['swift', 'objc']):
                    warnings.append("平台设置为iOS，但未启用Swift或Objective-C")
            elif self.platform == 'android':
                if not any(lang in self.obfuscation_rules.enabled_languages for lang in ['java', 'kotlin']):
                    warnings.append("平台设置为Android，但未启用Java或Kotlin")

        # 记录警告（如果有日志记录器）
        if warnings and self.logging.verbose:
            for warning in warnings:
                logger.warning(f"[CONFIG] {warning}")

        return errors
    
    def __post_init__(self):
        """初始化文件缓存容器"""
        # ReservedSymbols 类已经在自己的 __post_init__ 方法中初始化了内置配置
        # 这里只需要初始化文件缓存容器
        self._file_cache_key: Optional[Tuple] = None
        self._project_files_cache: List[str] = []
        self._language_file_cache: Dict[str, List[str]] = {}

    def invalidate_file_cache(self):
        """显式使文件缓存失效"""
        self._file_cache_key = None
        self._project_files_cache = []
        self._language_file_cache = {}

    def _compute_file_cache_key(self) -> Tuple:
        """计算当前过滤条件的缓存键"""
        include_ext = tuple(sorted(self.file_filters.include_extensions))
        exclude_dirs = tuple(sorted(self.file_filters.exclude_directories))
        exclude_files = tuple(sorted(self.file_filters.exclude_files))
        return (
            self.project_path,
            include_ext,
            exclude_dirs,
            exclude_files
        )

    def _ensure_project_file_cache(self):
        """确保项目文件缓存有效"""
        import glob
        import os

        cache_key = self._compute_file_cache_key()
        if cache_key == self._file_cache_key:
            return

        if not self.project_path or not os.path.exists(self.project_path):
            self._project_files_cache = []
            self._language_file_cache = {}
            self._file_cache_key = cache_key
            return

        files: List[str] = []
        for ext in self.file_filters.include_extensions:
            pattern = os.path.join(self.project_path, '**', f'*{ext}')
            files.extend(glob.glob(pattern, recursive=True))

        filtered_files = [
            file_path for file_path in files
            if self.file_filters.should_process_file(file_path)
        ]

        self._project_files_cache = filtered_files
        self._language_file_cache = {}
        self._file_cache_key = cache_key

    def get_project_files(self) -> List[str]:
        """获取项目中所有符合条件的源文件（带缓存）"""
        self._ensure_project_file_cache()
        return list(self._project_files_cache)
    
    def _get_language_files(self, cache_key: str, matcher) -> List[str]:
        """通用的语言文件获取逻辑"""
        import os

        manual_list = getattr(self, f"{cache_key}_files", None)
        if manual_list:
            return [f for f in manual_list if os.path.exists(f)]

        self._ensure_project_file_cache()
        if cache_key not in self._language_file_cache:
            self._language_file_cache[cache_key] = [
                path for path in self._project_files_cache if matcher(path)
            ]
        return list(self._language_file_cache[cache_key])

    def get_swift_files(self) -> List[str]:
        """获取Swift文件列表"""
        return self._get_language_files('swift', lambda f: f.endswith('.swift'))

    def get_objc_files(self) -> List[str]:
        """获取Objective-C文件列表"""
        return self._get_language_files('objc', lambda f: f.endswith(('.m', '.mm', '.h')))

    def get_kotlin_files(self) -> List[str]:
        """获取Kotlin文件列表"""
        return self._get_language_files('kotlin', lambda f: f.endswith('.kt'))

    def get_java_files(self) -> List[str]:
        """获取Java文件列表"""
        return self._get_language_files('java', lambda f: f.endswith('.java'))
    
    def should_obfuscate_language(self, language: str) -> bool:
        """检查是否应该混淆指定语言"""
        return self.is_language_enabled(language)
    
    def get_backup_path(self, original_path: str) -> str:
        """获取备份文件路径"""
        import os
        relative_path = os.path.relpath(original_path, self.project_path)
        return os.path.join(self.backup_dir, relative_path)
    
    def get_output_path(self, original_path: str) -> str:
        """获取输出文件路径"""
        import os
        relative_path = os.path.relpath(original_path, self.project_path)
        return os.path.join(self.output_dir, relative_path)
